#include "lm_conf_playback_wrapper.h"

namespace lm {
	void CALLBACK FuncPlaybackOnPlaybackOpenCB(
		int result, void* clientdata) {
		ConfPlaybackWrapper* wrapper = reinterpret_cast<ConfPlaybackWrapper*>(clientdata);
		wrapper->OnPlaybackOpenCB(result);
	}

	void CALLBACK FuncPlaybackOnPlaybackPlayCB(
		int result, void* clientdata) {
		ConfPlaybackWrapper* wrapper = reinterpret_cast<ConfPlaybackWrapper*>(clientdata);
		wrapper->OnPlaybackPlayCB(result);
	}

	void CALLBACK FuncPlaybackOnPlaybackPauseCB(
		int result, void* clientdata) {
		ConfPlaybackWrapper* wrapper = reinterpret_cast<ConfPlaybackWrapper*>(clientdata);
		wrapper->OnPlaybackPauseCB(result);
	}

	void CALLBACK FuncPlaybackOnPlaybackContinueCB(
		int result, void* clientdata) {
		ConfPlaybackWrapper* wrapper = reinterpret_cast<ConfPlaybackWrapper*>(clientdata);
		wrapper->OnPlaybackContinueCB(result);
	}

	void CALLBACK FuncPlaybackOnPlaybackCompleteCB(
		void* clientdata) {
		ConfPlaybackWrapper* wrapper = reinterpret_cast<ConfPlaybackWrapper*>(clientdata);
		wrapper->OnPlaybackCompleteCB();
	}

	void CALLBACK FuncPlaybackOnRepairBeginCB(
		int error, void* clientdata) {
		ConfPlaybackWrapper* wrapper = reinterpret_cast<ConfPlaybackWrapper*>(clientdata);
		wrapper->OnRepairBeginCB(error);
	}

	void CALLBACK FuncPlaybackOnRepairEndCB(
		int error, void* clientdata) {
		ConfPlaybackWrapper* wrapper = reinterpret_cast<ConfPlaybackWrapper*>(clientdata);
		wrapper->OnRepairEndCB(error);
	}

	void CALLBACK FuncPlaybackOnRepairProgressCB(
		int64_t currpos, int64_t duration, void* clientdata) {
		ConfPlaybackWrapper* wrapper = reinterpret_cast<ConfPlaybackWrapper*>(clientdata);
		wrapper->OnRepairProgressCB(currpos, duration);
	}

	void ConfPlaybackWrapper::OnPlaybackOpenCB(int result) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnPlaybackOpen(result);
		}
	}

	void ConfPlaybackWrapper::OnPlaybackPlayCB(int result) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnPlaybackPlay(result);
		}
	}

	void ConfPlaybackWrapper::OnPlaybackPauseCB(int result) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnPlaybackPause(result);
		}
	}

	void ConfPlaybackWrapper::OnPlaybackContinueCB(int result) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnPlaybackContinue(result);
		}
	}

	void ConfPlaybackWrapper::OnPlaybackCompleteCB() {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnPlaybackComplete();
		}
	}

	void ConfPlaybackWrapper::OnRepairBeginCB(int error) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnRepairBegin(error);
		}
	}

	void ConfPlaybackWrapper::OnRepairEndCB(int error) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnRepairEnd(error);
		}
	}

	void ConfPlaybackWrapper::OnRepairProgressCB(int64_t currpos, int64_t duration) {
		for (ObserverList::iterator it = observer_list_.begin(); it != observer_list_.end(); it++) {
			(*it)->OnRepairProgress(currpos, duration);
		}
	}

	bool ConfPlaybackWrapper::IsVaildPlaybackFile(const char* file_name, bool& needRepairIfValid) {
		int v = 0;
		int ret = lm_conf_playback_IsVaildPlaybackFile(file_name, &v);
		needRepairIfValid = !!v;
		return !!ret;
	}

	ConfPlaybackWrapper::ConfPlaybackWrapper(native_object_t c_object)
		: c_object_(c_object) {
		ConfPlaybackCallback cb;
		memset(&cb, 0, sizeof(cb));
		cb.client_data_ = this;
		cb.OnPlaybackComplete_ = FuncPlaybackOnPlaybackCompleteCB;
		cb.OnPlaybackContinue_ = FuncPlaybackOnPlaybackContinueCB;
		cb.OnPlaybackOpen_ = FuncPlaybackOnPlaybackOpenCB;
		cb.OnPlaybackPause_ = FuncPlaybackOnPlaybackPauseCB;
		cb.OnPlaybackPlay_ = FuncPlaybackOnPlaybackPlayCB;
		cb.OnRepairBegin_ = FuncPlaybackOnRepairBeginCB;
		cb.OnRepairEnd_ = FuncPlaybackOnRepairEndCB;
		cb.OnRepairProgress_ = FuncPlaybackOnRepairProgressCB;
		lm_conf_playback_set_callback(c_object_, &cb);
	}

	ConfPlaybackWrapper::~ConfPlaybackWrapper() {
	}

	void ConfPlaybackWrapper::AddObserver(Observer* observer) {
		if (std::find(observer_list_.begin(), observer_list_.end(), observer) == observer_list_.end())
			observer_list_.push_back(observer);
	}

	void ConfPlaybackWrapper::RemoveObserver(Observer* observer) {
		ObserverList::iterator it = std::find(observer_list_.begin(), observer_list_.end(), observer);
		if (it != observer_list_.end())
			observer_list_.erase(it);
	}

	int ConfPlaybackWrapper::StartPlayback(const char* file_name) {
		return lm_conf_playback_StartPlayback(c_object_, file_name);
	}

	int ConfPlaybackWrapper::PlayPlayback(const char** playaccounts, int count) {
		return lm_conf_playback_PlayPlayback(c_object_, playaccounts, count);
	}

	int ConfPlaybackWrapper::PausePlayback() {
		return lm_conf_playback_PausePlayback(c_object_);
	}

	int ConfPlaybackWrapper::ContinuePlayback() {
		return lm_conf_playback_ContinuePlayback(c_object_);
	}

	int ConfPlaybackWrapper::StopPlayback() {
		return lm_conf_playback_StopPlayback(c_object_);
	}

	int ConfPlaybackWrapper::StartRepair(const char* file_name) {
		return lm_conf_playback_StartRepair(c_object_, file_name);
	}

	int ConfPlaybackWrapper::StopRepair() {
		return lm_conf_playback_StopRepair(c_object_);
	}

	bool ConfPlaybackWrapper::IsPlaybacking() {
		return !!lm_conf_playback_IsPlaybacking(c_object_);
	}

	bool ConfPlaybackWrapper::IsRepairing() {
		return !!lm_conf_playback_IsRepairing(c_object_);
	}

	int ConfPlaybackWrapper::GetRecSessionCount(LMRecSessionType type) {
		return lm_conf_playback_GetRecSessionCount(c_object_, type);
	}

	int ConfPlaybackWrapper::EnumRecSessionInfo(LMRecSessionType type, LMRecSessionInfo* info, int& count) {
		return lm_conf_playback_EnumRecSessionInfo(c_object_, type, info, &count);
	}

}